using System.Collections.Generic;
using Moq;
using NUnit.Framework;
using Tycho.Parser.Peg;
using Tycho.Parser.Syntax;

namespace Tycho.Parser.Tests.Syntax {
    [TestFixture]
    public class ProductionLookupSpecification {
        [Test]
        public void IndexGetShouldReturnLastProductionIfNullIsSpecifiedAndIsFirst () {
            var defaultLanguage = new Language ("default");
            var production = new Mock<Production<ParseContext>> ();
            var productionLookup = new ProductionLookup (defaultLanguage, new Dictionary<Language, Production<ParseContext>> (), production.Object);
            Assert.AreSame (production.Object, productionLookup [null]);
        }

        [Test]
        public void IndexGetShouldReturnLastProductionIfDefaultLanguageIsSpecifiedAndIsFirst () {
            var defaultLanguage = new Language ("default");
            var production = new Mock<Production<ParseContext>> ();
            var productionLookup = new ProductionLookup (defaultLanguage, new Dictionary<Language, Production<ParseContext>> (), production.Object);
            Assert.AreSame (production.Object, productionLookup [defaultLanguage]);
        }

        [Test]
        public void IndexGetShouldReturnProductionKeyedFromDefaultLanguageIfNullIsSpecified () {
            var defaultLanguage = new Language ("default");
            var lastProduction = new Mock<Production<ParseContext>> ();
            var production = new Mock<Production<ParseContext>> ();
            var productions = new Dictionary<Language, Production<ParseContext>> {{defaultLanguage, production.Object} };
            var productionLookup = new ProductionLookup (defaultLanguage, productions, lastProduction.Object);
            productionLookup.IsFirst = false;
            Assert.AreSame (production.Object, productionLookup [null]);
        }

        [Test]
        public void IndexGetShouldReturnProductionFromDictionary () {
            var defaultLanguage = new Language ("default");
            var lookupLanguage = new Language ("lookup");
            var lastProduction = new Mock<Production<ParseContext>> ();
            var production = new Mock<Production<ParseContext>> ();
            var productions = new Dictionary<Language, Production<ParseContext>> { { lookupLanguage, production.Object } };
            var productionLookup = new ProductionLookup (defaultLanguage, productions, lastProduction.Object);
            productionLookup.IsFirst = false;
            Assert.AreSame (production.Object, productionLookup [lookupLanguage]);
        }

        [Test]
        public void IndexGetShouldReturnProductionFromDictionaryIfDefaultLanguageSpecifiedAndNotIsFirst () {
            var defaultLanguage = new Language ("default");
            var lastProduction = new Mock<Production<ParseContext>> ();
            var production = new Mock<Production<ParseContext>> ();
            var productions = new Dictionary<Language, Production<ParseContext>> { { defaultLanguage, production.Object } };
            var productionLookup = new ProductionLookup (defaultLanguage, productions, lastProduction.Object);
            productionLookup.IsFirst = false;
            Assert.AreSame (production.Object, productionLookup [defaultLanguage]);
        }
    }
}